package cn.doitedu.ml.doit13.linageregression

import cn.doitedu.commons.util.SparkUtil
import org.apache.spark.ml.linalg.Vectors
import org.apache.spark.ml.regression.LinearRegression
import org.apache.spark.sql.Row

/**
 * 线性回归算法调用示例
 * 寻找房价和  面积、楼层之间的线性函数关系
 */
object LinearRegressionDemo {

  def main(args: Array[String]): Unit = {

    val spark = SparkUtil.getSparkSession(this.getClass.getSimpleName)
    import spark.implicits._

    // 加载样本集
    val sample = spark.read.option("header",true).option("inferSchema",true).csv("userprofile/data/demo/house/h.csv")

    // 样本数据特征向量化
    val vecSample = sample.rdd.map({
      case Row(area:Double,floor:Double,price:Double)
        =>
        val features = Vectors.dense(Array(area, floor))
        (features,price)
    }).toDF("features","label")


    // 构造算法工具
    val regression = new LinearRegression()
      .setFeaturesCol("features")
      .setLabelCol("label")
      .setRegParam(0.01)  // 正则化参数，用于防止过拟合 ；样本中离群点越多，这个正则化参数可以调大

    val model = regression.fit(vecSample)



    // 加载待预测数据集
    val test = spark.read.option("header",true).option("inferSchema",true).csv("userprofile/data/demo/house/t.csv")

    // 样本数据特征向量化
    val vecTest = test.rdd.map({
      case Row(id:Integer,area:Double,floor:Double)
      =>
        val features = Vectors.dense(Array(area, floor))
        (id,features)
    }).toDF("id","features")


    // 用模型去预测数据
    val predict = model.transform(vecTest)
    predict.show(100,false)

    spark.close()
  }

}
